﻿using System.Xml.Serialization;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using System;
using System.Reflection;
using System.Xml.Schema;
using SS.Net.AppGen.Utils;

namespace SS.Net.AppGen.Models
{
    /// <summary>
    /// The class is corresponding with the element WebConfiguration in WebConfiguration.xml file
    /// </summary>
    public class WebConfiguration
    {
        #region Properties

        /// <summary>
        /// The attribute DataSource
        /// </summary>
        [XmlAttribute("DataBaseType")]
        public string DataBaseType { get; set; }

        /// <summary>
        /// The attribute DataSource
        /// </summary>
        [XmlAttribute("DataSource")]
        public string DataSource { get; set; }

        /// <summary>
        /// The attribute DataBaseName
        /// </summary>
        [XmlAttribute("DataBaseName")]
        public string DataBaseName { get; set; }

        /// <summary>
        /// The attribute UserName
        /// </summary>
        [XmlAttribute("UserName")]
        public string UserName { get; set; }

        /// <summary>
        /// The attribute Password
        /// </summary>
        [XmlAttribute("Password")]
        public string Password { get; set; }

        /// <summary>
        /// The attribute NameSpace
        /// </summary>
        [XmlAttribute("NameSpace")]
        public string NameSpace { get; set; }

        /// <summary>
        /// The element Settings
        /// </summary>
        [XmlElement("Settings")]
        public Settings Settings { get; set; }

        /// <summary>
        /// Array of element Table
        /// </summary>
        [XmlArray("ConfigTables")]
        [XmlArrayItem("ConfigTable")]
        public List<ConfigTable> ConfigTables { get; set; }

        #endregion

        #region Fields

        /// <summary>
        /// Singleton pattern to guarantee only one instance of this class will be created
        /// </summary>
        private static WebConfiguration instance;

        /// <summary>
        /// Schema for XML WebConfiguration validation
        /// </summary>
        private static XmlSchema WebConfigurationSchema;

        /// <summary>
        /// Web configuration file
        /// </summary>
        private const string xmlWebConfiguration = "WebConfiguration.xml";

        /// <summary>
        /// Full name of xsd file WebConfiguration
        /// </summary>
        private const string xsdWebConfiguration = "WebConfiguration.xsd";

        #endregion

        #region Methods

        /// <summary>
        /// Get instance of this class
        /// </summary>
        /// <returns></returns>
        public static WebConfiguration Instance
        {
            get
            {
                if (instance == null)
                {
                    var cfgFile = Path.Combine(GetAppPath(), "Configs", xmlWebConfiguration);

                    // Create schemas
                    WebConfigurationSchema = IoC.Get<XmlValidator>().CreateSchema(xsdWebConfiguration);

                    // Validate xml content using schema setting
                    IoC.Get<XmlValidator>().ValidateXML(cfgFile, WebConfigurationSchema);

                    // Start to deserialize
                    using (XmlTextReader xreader = new XmlTextReader(cfgFile))
                    {
                        xreader.Namespaces = false;
                        try
                        {
                            var x = new XmlSerializer(typeof(WebConfiguration));
                            instance = x.Deserialize(xreader) as WebConfiguration;
                        }
                        catch (Exception ex)
                        {
                            throw new Exception(string.Format("Cannot deserialize WebConfiguration, WebConfiguration => {0}", ex.Message));
                        }
                    }
                }
                return instance;
            }
        }

        /// <summary>
        /// Get application path
        /// </summary>
        /// <returns></returns>
        private static string GetAppPath()
        {
            return Directory.GetParent(Assembly.GetExecutingAssembly().Location).FullName;
        }

        #endregion
    }

    /// <summary>
    /// WebConfiguration > Settings
    /// </summary>
    public class Settings
    {
        #region Properties

        [XmlAttribute("DefaultImage")]
        public string DefaultImage { get; set; }

        [XmlAttribute("UploadImageDirectory")]
        public string UploadImageDirectory { get; set; }

        [XmlAttribute("UserTable")]
        public string UserTable { get; set; }

        [XmlAttribute("SkipTables")]
        public string SkipTables { get; set; }

        #endregion

        public Settings()
        {
            this.UserTable = string.Empty;
        }
    }

    /// <summary>
    /// WebConfiguration > ConfigTable
    /// </summary>
    public class ConfigTable
    {
        #region Properties

        /// <summary>
        /// The attribute Name
        /// </summary>
        [XmlAttribute("Name")]
        public string Name { get; set; }

        /// <summary>
        /// The attribute AttributeImage
        /// </summary>
        [XmlAttribute("AttributeImage")]
        public string AttributeImage { get; set; }

        /// <summary>
        /// The attribute AttributeFCK
        /// </summary>
        [XmlAttribute("AttributeFCK")]
        public string AttributeFCK { get; set; }

        /// <summary>
        /// The attribute IsWithAjax
        /// </summary>
        [XmlAttribute("IsWithAjax")]
        public string IsWithAjax { get; set; }

        /// <summary>
        /// The attribute MainForeignKey
        /// </summary>
        [XmlAttribute("ForeignKey")]
        public string MainForeignKey { get; set; }

        #endregion
    }
}
